home *** CD-ROM | disk | FTP | other *** search
/ GameStar 2004 April / Gamestar_61_2004-04_dvdb.iso / DVDStar / Editace / hltp.exe / {app} / Source Code / Half-Life Model Viewer / src / ControlPanel.cpp < prev    next >
C/C++ Source or Header  |  2002-01-15  |  28KB  |  1,011 lines

  1. //
  2. //                 Half-Life Model Viewer (c) 1999 by Mete Ciragan
  3. //
  4. // file:           ControlPanel.cpp
  5. // last modified:  Oct 20 1999, Mete Ciragan
  6. // copyright:      The programs and associated files contained in this
  7. //                 distribution were developed by Mete Ciragan. The programs
  8. //                 are not in the public domain, but they are freely
  9. //                 distributable without licensing fees. These programs are
  10. //                 provided without guarantee or warrantee expressed or
  11. //                 implied.
  12. //
  13. // version:        1.24
  14. //
  15. // email:          mete@swissquake.ch
  16. // web:            http://www.swissquake.ch/chumbalum-soft/
  17. //
  18. #include "ControlPanel.h"
  19. #include "ViewerSettings.h"
  20. #include "StudioModel.h"
  21. #include "GlWindow.h"
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <mx/mx.h>
  26. #include <mx/mxBmp.h>
  27.  
  28.  
  29.  
  30. extern char g_appTitle[];
  31.  
  32.  
  33.  
  34. bool swap3dfxgl (bool b);
  35.  
  36.  
  37.  
  38. ControlPanel *g_ControlPanel = 0;
  39. bool g_bStopPlaying = false;
  40. static int g_nCurrFrame = 0;
  41.  
  42.  
  43.  
  44. ControlPanel::ControlPanel (mxWindow *parent)
  45. : mxWindow (parent, 0, 0, 0, 0, "Control Panel", mxWindow::Normal)
  46. {
  47.     InitViewerSettings ();
  48.  
  49.     // create tabcontrol with subdialog windows
  50.     tab = new mxTab (this, 0, 0, 0, 0, IDC_TAB);
  51. #ifdef WIN32
  52.     SetWindowLong ((HWND) tab->getHandle (), GWL_EXSTYLE, WS_EX_CLIENTEDGE);
  53. #endif
  54.  
  55.     mxWindow *wRender = new mxWindow (this, 0, 0, 0, 0);
  56.     tab->add (wRender, "Render");
  57.     cRenderMode = new mxChoice (wRender, 5, 5, 100, 22, IDC_RENDERMODE);
  58.     cRenderMode->add ("Wireframe");
  59.     cRenderMode->add ("Flatshaded");
  60.     cRenderMode->add ("Smoothshaded");
  61.     cRenderMode->add ("Textured");
  62.     cRenderMode->select (3);
  63.     mxToolTip::add (cRenderMode, "Select Render Mode");
  64.     slTransparency = new mxSlider (wRender, 5, 28, 100, 18, IDC_TRANSPARENCY);
  65.     slTransparency->setValue (100);
  66.     mxToolTip::add (slTransparency, "Model Transparency");
  67.     cbGround = new mxCheckBox (wRender, 110, 5, 150, 20, "Ground", IDC_GROUND);
  68.     cbMirror = new mxCheckBox (wRender, 110, 25, 150, 20, "Mirror Model On Ground", IDC_MIRROR);
  69.     cbBackground = new mxCheckBox (wRender, 110, 45, 150, 20, "Background", IDC_BACKGROUND);
  70.     mxCheckBox *cbHitBoxes = new mxCheckBox (wRender, 110, 65, 150, 20, "Hit Boxes", IDC_HITBOXES);
  71.     mxCheckBox *cbBones = new mxCheckBox (wRender, 5, 65, 100, 20, "Bones", IDC_BONES);
  72.     mxCheckBox *cbAttachments = new mxCheckBox (wRender, 5, 45, 100, 20, "Attachments", IDC_ATTACHMENTS);
  73.  
  74. #ifdef HAVE_SCALE
  75.     leMeshScale = new mxLineEdit (wRender, 270, 5, 50, 18, "1.0");
  76.     mxToolTip::add (leMeshScale, "Mesh Scale");
  77.     leBoneScale = new mxLineEdit (wRender, 270, 25, 50, 18, "1.0");
  78.     mxToolTip::add (leBoneScale, "Bone Scale");
  79.     mxButton *bMeshScale = new mxButton (wRender, 325, 5, 50, 18, "Scale", 10001);
  80.     mxButton *bBoneScale = new mxButton (wRender, 325, 25, 50, 18, "Scale", 10002);
  81. #endif
  82.  
  83.     mxWindow *wSequence = new mxWindow (this, 0, 0, 0, 0);
  84.     tab->add (wSequence, "Sequence");
  85.     cSequence = new mxChoice (wSequence, 5, 5, 200, 22, IDC_SEQUENCE);    
  86.     mxToolTip::add (cSequence, "Select Sequence");
  87.     slSpeedScale = new mxSlider (wSequence, 5, 32, 200, 18, IDC_SPEEDSCALE);
  88.     slSpeedScale->setRange (0, 200);
  89.     slSpeedScale->setValue (40);
  90.     mxToolTip::add (slSpeedScale, "Speed Scale");
  91.     tbStop = new mxToggleButton (wSequence, 5, 55, 60, 22, "Stop", IDC_STOP);
  92.     mxToolTip::add (tbStop, "Stop Playing");
  93.     bPrevFrame = new mxButton (wSequence, 70, 55, 30, 22, "<<", IDC_PREVFRAME);
  94.     bPrevFrame->setEnabled (false);
  95.     mxToolTip::add (bPrevFrame, "Prev Frame");
  96.     leFrame = new mxLineEdit (wSequence, 105, 55, 50, 22, "", IDC_FRAME); 
  97.     leFrame->setEnabled (false);
  98.     mxToolTip::add (leFrame, "Set Frame");
  99.     bNextFrame = new mxButton (wSequence, 160, 55, 30, 22, ">>", IDC_NEXTFRAME);
  100.     bNextFrame->setEnabled (false);
  101.     mxToolTip::add (bNextFrame, "Next Frame");
  102.  
  103.  
  104.     mxWindow *wBody = new mxWindow (this, 0, 0, 0, 0);
  105.     tab->add (wBody, "Body");
  106.     cBodypart = new mxChoice (wBody, 5, 5, 100, 22, IDC_BODYPART);
  107.     mxToolTip::add (cBodypart, "Choose a bodypart");
  108.     cSubmodel = new mxChoice (wBody, 110, 5, 100, 22, IDC_SUBMODEL);
  109.     mxToolTip::add (cSubmodel, "Choose a submodel of current bodypart");
  110.     cController = new mxChoice (wBody, 5, 30, 100, 22, IDC_CONTROLLER);    
  111.     mxToolTip::add (cController, "Choose a bone controller");
  112.     slController = new mxSlider (wBody, 105, 32, 100, 18, IDC_CONTROLLERVALUE);
  113.     slController->setRange (0, 45);
  114.     mxToolTip::add (slController, "Change current bone controller value");
  115.     lModelInfo1 = new mxLabel (wBody, 220, 5, 120, 100, "No Model.");
  116.     lModelInfo2 = new mxLabel (wBody, 340, 5, 120, 100, "");
  117.     cSkin = new mxChoice (wBody, 5, 55, 100, 22, IDC_SKINS);
  118.     mxToolTip::add (cSkin, "Choose a skin family");
  119.  
  120.     mxWindow *wTexture = new mxWindow (this, 0, 0, 0, 0);
  121.     tab->add (wTexture, "Texture");
  122.     cTextures = new mxChoice (wTexture, 5, 5, 150, 22, IDC_TEXTURES);
  123.     mxToolTip::add (cTextures, "Choose a texture");
  124.     
  125.     new mxButton (wTexture, 160, 5, 75, 18, "Export", IDC_EXPORTTEXTURE);
  126.     new mxButton (wTexture, 160, 25, 75, 18, "Import", IDC_IMPORTTEXTURE);
  127.     new mxButton (wTexture, 160, 45, 75, 18, "Save Model", IDC_SAVEMODEL);
  128.     lTexSize = new mxLabel (wTexture, 162, 70, 150, 18, "Width x Height");
  129.     cbChrome = new mxCheckBox (wTexture, 5, 30, 150, 22, "Chrome Effect", IDC_CHROME);
  130.     mxToolTip::add (new mxSlider (wTexture, 5, 57, 150, 18, IDC_TEXTURESCALE), "Scale texture size");
  131.     
  132. #ifdef WIN32
  133.     mxWindow *wFullscreen = new mxWindow (this, 0, 0, 0, 0);
  134.     tab->add (wFullscreen, "Fullscreen");
  135.  
  136.     // Create widgets for the Fullscreen Tab
  137.     mxLabel *lResolution = new mxLabel (wFullscreen, 5, 7, 50, 18, "Resolution");
  138.     leWidth = new mxLineEdit (wFullscreen, 5, 5, 50, 22, "800");
  139.     mxLabel *lX = new mxLabel (wFullscreen, 65, 7, 22, 22, "x");
  140.     leHeight = new mxLineEdit (wFullscreen, 82, 5, 50, 22, "600");
  141.     //cb3dfxOpenGL = new mxCheckBox (wFullscreen, 5, 30, 130, 22, "3Dfx OpenGL");
  142.     mxButton *bView = new mxButton (wFullscreen, 140, 5, 75, 22, "Fullscreen!", IDC_FULLSCREEN);
  143. #endif
  144.  
  145.     g_ControlPanel = this;
  146. }
  147.  
  148.  
  149.  
  150. ControlPanel::~ControlPanel ()
  151. {
  152. }
  153.  
  154.  
  155.  
  156. int
  157. ControlPanel::handleEvent (mxEvent *event)
  158. {
  159.     static char str[128];
  160.  
  161.     if (event->event == mxEvent::Size)
  162.     {
  163.         tab->setBounds (0, 0, event->width, event->height);
  164.         return 1;
  165.     }
  166.  
  167.     switch (event->action)
  168.     {
  169.         case IDC_TAB:
  170.         {
  171.             g_viewerSettings.showTexture = (tab->getSelectedIndex () == 3);
  172.         }
  173.         break;
  174.  
  175.         case IDC_RENDERMODE:
  176.         {
  177.             int index = cRenderMode->getSelectedIndex ();
  178.             if (index >= 0)
  179.             {
  180.                 setRenderMode (index);
  181.             }
  182.         }
  183.         break;
  184.  
  185.         case IDC_TRANSPARENCY:
  186.         {
  187.             int value = slTransparency->getValue ();
  188.             g_viewerSettings.transparency = (float) value / 100.0f; 
  189.         }
  190.         break;
  191.  
  192.         case IDC_GROUND:
  193.             setShowGround (((mxCheckBox *) event->widget)->isChecked ());
  194.             break;
  195.  
  196.         case IDC_MIRROR:
  197.             setMirror (((mxCheckBox *) event->widget)->isChecked ());
  198.             break;
  199.  
  200.         case IDC_BACKGROUND:
  201.             setShowBackground (((mxCheckBox *) event->widget)->isChecked ());
  202.             break;
  203.  
  204.         case IDC_HITBOXES:
  205.             g_viewerSettings.showHitBoxes = ((mxCheckBox *) event->widget)->isChecked ();
  206.             break;
  207.  
  208.         case IDC_BONES:
  209.             g_viewerSettings.showBones = ((mxCheckBox *) event->widget)->isChecked ();
  210.             break;
  211.  
  212.         case IDC_ATTACHMENTS:
  213.             g_viewerSettings.showAttachments = ((mxCheckBox *) event->widget)->isChecked ();
  214.             break;
  215.  
  216.         case IDC_SEQUENCE:
  217.         {
  218.             int index = cSequence->getSelectedIndex ();
  219.             if (index >= 0)
  220.             {
  221.                 setSequence (index);
  222.             }
  223.         }
  224.         break;
  225.  
  226.         case IDC_SPEEDSCALE:
  227.         {
  228.             int v = ((mxSlider *) event->widget)->getValue ();
  229.             g_viewerSettings.speedScale = (float) (v * 5) / 200.0f;
  230.         }
  231.         break;
  232.  
  233.         case IDC_STOP:
  234.         {
  235.             if (tbStop->isChecked ())
  236.             {
  237.                 tbStop->setLabel ("Play");
  238.                 g_bStopPlaying = true;
  239.                 g_nCurrFrame = g_studioModel.SetFrame (-1);
  240.                 sprintf (str, "%d", g_nCurrFrame);
  241.                 leFrame->setLabel (str);
  242.                 bPrevFrame->setEnabled (true);
  243.                 leFrame->setEnabled (true);
  244.                 bNextFrame->setEnabled (true);
  245.             }
  246.             else
  247.             {
  248.                 tbStop->setLabel ("Stop");
  249.                 g_bStopPlaying = false;
  250.                 bPrevFrame->setEnabled (false);
  251.                 leFrame->setEnabled (false);
  252.                 bNextFrame->setEnabled (false);
  253.             }
  254.         }
  255.         break;
  256.  
  257.         case IDC_PREVFRAME:
  258.         {
  259.             g_nCurrFrame = g_studioModel.SetFrame (g_nCurrFrame - 1);
  260.             sprintf (str, "%d", g_nCurrFrame);
  261.             leFrame->setLabel (str);
  262.         }
  263.         break;
  264.  
  265.         case IDC_FRAME:
  266.         {
  267.             g_nCurrFrame = atoi (leFrame->getLabel ());
  268.             g_nCurrFrame = g_studioModel.SetFrame (g_nCurrFrame);
  269.         }
  270.         break;
  271.  
  272.         case IDC_NEXTFRAME:
  273.         {
  274.             g_nCurrFrame = g_studioModel.SetFrame (g_nCurrFrame + 1);
  275.             sprintf (str, "%d", g_nCurrFrame);
  276.             leFrame->setLabel (str);
  277.         }
  278.         break;
  279.  
  280.         case IDC_BODYPART:
  281.         {
  282.             int index = cBodypart->getSelectedIndex ();
  283.             if (index >= 0)
  284.             {
  285.                 setBodypart (index);
  286.  
  287.             }
  288.         }
  289.         break;
  290.  
  291.         case IDC_SUBMODEL:
  292.         {
  293.             int index = cSubmodel->getSelectedIndex ();
  294.             if (index >= 0)
  295.             {
  296.                 setSubmodel (index);
  297.  
  298.             }
  299.         }
  300.         break;
  301.  
  302.         case IDC_CONTROLLER:
  303.         {
  304.             int index = cController->getSelectedIndex ();
  305.             if (index >= 0)
  306.                 setBoneController (index);
  307.         }
  308.         break;
  309.  
  310.         case IDC_CONTROLLERVALUE:
  311.         {
  312.             int index = cController->getSelectedIndex ();
  313.             if (index >= 0)
  314.                 setBoneControllerValue (index, (float) slController->getValue ());
  315.         }
  316.         break;
  317.  
  318.         case IDC_SKINS:
  319.         {
  320.             int index = cSkin->getSelectedIndex ();
  321.             if (index >= 0)
  322.             {
  323.                 g_studioModel.SetSkin (index);
  324.                 g_viewerSettings.skin = index;
  325.                 d_GlWindow->redraw ();
  326.             }
  327.         }
  328.         break;
  329.  
  330.         case IDC_TEXTURES:
  331.         {
  332.             int index = cTextures->getSelectedIndex ();
  333.             if (index >= 0)
  334.             {
  335.                 g_viewerSettings.texture = index;
  336.                 studiohdr_t *hdr = g_studioModel.getTextureHeader ();
  337.                 if (hdr)
  338.                 {
  339.                     mstudiotexture_t *ptexture = (mstudiotexture_t *) ((byte *) hdr + hdr->textureindex) + index;
  340.                     char str[32];
  341.                     sprintf (str, "Size: %d x %d", ptexture->width, ptexture->height);
  342.                     lTexSize->setLabel (str);
  343.                     cbChrome->setChecked ((ptexture->flags & STUDIO_NF_CHROME) == STUDIO_NF_CHROME);
  344.                 }
  345.                 d_GlWindow->redraw ();
  346.             }
  347.         }
  348.         break;
  349.  
  350.         case IDC_CHROME:
  351.         {
  352.             studiohdr_t *hdr = g_studioModel.getTextureHeader ();
  353.             if (hdr)
  354.             {
  355.                 mstudiotexture_t *ptexture = (mstudiotexture_t *) ((byte *) hdr + hdr->textureindex) + g_viewerSettings.texture;
  356.                 if (cbChrome->isChecked ())
  357.                     ptexture->flags |= STUDIO_NF_CHROME;
  358.                 else
  359.                     ptexture->flags &= ~STUDIO_NF_CHROME;
  360.             }
  361.         }
  362.         break;
  363.  
  364.         case IDC_EXPORTTEXTURE:
  365.         {
  366.             char *ptr = (char *) mxGetSaveFileName (this, "", "*.bmp");
  367.             if (!ptr)
  368.                 break;
  369.  
  370.             char filename[256];
  371.             char ext[16];
  372.  
  373.             strcpy (filename, ptr);
  374.             strcpy (ext, mx_getextension (filename));
  375.             if (mx_strcasecmp (ext, ".bmp"))
  376.                 strcat (filename, ".bmp");
  377.  
  378.             studiohdr_t *phdr = g_studioModel.getTextureHeader ();
  379.             if (phdr)
  380.             {
  381.                 mxImage image;
  382.                 mstudiotexture_t *ptexture = (mstudiotexture_t *) ((byte *) phdr + phdr->textureindex) + g_viewerSettings.texture;
  383.                 image.width = ptexture->width;
  384.                 image.height = ptexture->height;
  385.                 image.bpp = 8;
  386.                 image.data = (void *) ((byte *) phdr + ptexture->index);
  387.                 image.palette = (void *) ((byte *) phdr + ptexture->width * ptexture->height + ptexture->index);
  388.                 if (!mxBmpWrite (filename, &image))
  389.                     mxMessageBox (this, "Error writing .BMP texture.", g_appTitle, MX_MB_OK | MX_MB_ERROR);
  390.                 image.data = 0;
  391.                 image.palette = 0;
  392.             }
  393.         }
  394.         break;
  395.  
  396.         case IDC_IMPORTTEXTURE:
  397.         {
  398.             char *ptr = (char *) mxGetOpenFileName (this, "", "*.bmp");
  399.             if (!ptr)
  400.                 break;
  401.  
  402.             char filename[256];
  403.             char ext[16];
  404.  
  405.             strcpy (filename, ptr);
  406.             strcpy (ext, mx_getextension (filename));
  407.             if (mx_strcasecmp (ext, ".bmp"))
  408.                 strcat (filename, ".bmp");
  409.  
  410.             mxImage *image = mxBmpRead (filename);
  411.             if (!image)
  412.             {
  413.                 mxMessageBox (this, "Error loading .BMP texture.", g_appTitle, MX_MB_OK | MX_MB_ERROR);
  414.                 return 1;
  415.             }
  416.  
  417.             if (!image->palette)
  418.             {
  419.                 delete image;
  420.                 mxMessageBox (this, "Error loading .BMP texture.  Must be 8-bit!", g_appTitle, MX_MB_OK | MX_MB_ERROR);
  421.                 return 1;
  422.             }
  423.  
  424.             studiohdr_t *phdr = g_studioModel.getTextureHeader ();
  425.             if (phdr)
  426.             {
  427.                 mstudiotexture_t *ptexture = (mstudiotexture_t *) ((byte *) phdr + phdr->textureindex) + g_viewerSettings.texture;
  428.                 if (image->width == ptexture->width && image->height == ptexture->height)
  429.                 {
  430.                     memcpy ((byte *) phdr + ptexture->index, image->data, image->width * image->height);
  431.                     memcpy ((byte *) phdr + ptexture->index + image->width * image->height, image->palette, 768);
  432.  
  433.                     g_studioModel.UploadTexture (ptexture, (byte *) phdr + ptexture->index, (byte *) phdr + ptexture->index + image->width * image->height, g_viewerSettings.texture + 3);
  434.                 }
  435.                 else
  436.                     mxMessageBox (this, "Texture must be of same size.", g_appTitle, MX_MB_OK | MX_MB_ERROR);
  437.             }
  438.  
  439.             delete image;
  440.             d_GlWindow->redraw ();
  441.         }
  442.         break;
  443.  
  444.         case IDC_SAVEMODEL:
  445.         {
  446.             char *ptr = (char *) mxGetSaveFileName (this, "", "*.mdl");
  447.             if (!ptr)
  448.                 break;
  449.  
  450.             char filename[256];
  451.             char ext[16];
  452.  
  453.             strcpy (filename, ptr);
  454.             strcpy (ext, mx_getextension (filename));
  455.             if (mx_strcasecmp (ext, ".mdl"))
  456.                 strcat (filename, ".mdl");
  457.  
  458.             if (!g_studioModel.SaveModel (filename))
  459.                 mxMessageBox (this, "Error saving model.", g_appTitle, MX_MB_OK | MX_MB_ERROR);
  460.             else
  461.                 strcpy (g_viewerSettings.modelFile, filename);
  462.         }
  463.         break;
  464.  
  465.         case IDC_TEXTURESCALE:
  466.         {
  467.             g_viewerSettings.textureScale =  1.0f + (float) ((mxSlider *) event->widget)->getValue () * 4.0f / 100.0f;
  468.             d_GlWindow->redraw ();
  469.         }
  470.         break;
  471.  
  472. #ifdef HAVE_SCALE
  473.         case 10001:
  474.         {
  475.             float scale = (float) atof (leMeshScale->getLabel ());
  476.             if (scale > 0.0f)
  477.             {
  478.                 g_studioModel.scaleMeshes (scale);
  479.             }
  480.         }
  481.         break;
  482.  
  483.         case 10002:
  484.         {
  485.             float scale = (float) atof (leBoneScale->getLabel ());
  486.             if (scale > 0.0f)
  487.             {
  488.                 g_studioModel.scaleBones (scale);
  489.             }
  490.         }
  491.         break;
  492. #endif
  493.  
  494. #ifdef WIN32
  495.         case IDC_FULLSCREEN:
  496.             fullscreen ();
  497.             break;
  498. #endif
  499.     }
  500.  
  501.     return 1;
  502. }
  503.  
  504.  
  505.  
  506. void
  507. ControlPanel::dumpModelInfo ()
  508. {
  509. #if 0
  510.     studiohdr_t *hdr = g_studioModel.getStudioHeader ();
  511.     if (hdr)
  512.     {
  513.         DeleteFile ("midump.txt");
  514.         FILE *file = fopen ("midump.txt", "wt");
  515.         if (file)
  516.         {
  517.             byte *phdr = (byte *) hdr;
  518.             int i;
  519.  
  520.             fprintf (file, "id: %c%c%c%c\n", phdr[0], phdr[1], phdr[2], phdr[3]);
  521.             fprintf (file, "version: %d\n", hdr->version);
  522.             fprintf (file, "name: \"%s\"\n", hdr->name);
  523.             fprintf (file, "length: %d\n\n", hdr->length);
  524.  
  525.             fprintf (file, "eyeposition: %f %f %f\n", hdr->eyeposition[0], hdr->eyeposition[1], hdr->eyeposition[2]);
  526.             fprintf (file, "min: %f %f %f\n", hdr->min[0], hdr->min[1], hdr->min[2]);
  527.             fprintf (file, "max: %f %f %f\n", hdr->max[0], hdr->max[1], hdr->max[2]);
  528.             fprintf (file, "bbmin: %f %f %f\n", hdr->bbmin[0], hdr->bbmin[1], hdr->bbmin[2]);
  529.             fprintf (file, "bbmax: %f %f %f\n", hdr->bbmax[0], hdr->bbmax[1], hdr->bbmax[2]);
  530.             
  531.             fprintf (file, "flags: %d\n\n", hdr->flags);
  532.  
  533.             fprintf (file, "numbones: %d\n", hdr->numbones);
  534.             for (i = 0; i < hdr->numbones; i++)
  535.             {
  536.                 mstudiobone_t *pbones = (mstudiobone_t *) (phdr + hdr->boneindex);
  537.                 fprintf (file, "\nbone %d.name: \"%s\"\n", i + 1, pbones[i].name);
  538.                 fprintf (file, "bone %d.parent: %d\n", i + 1, pbones[i].parent);
  539.                 fprintf (file, "bone %d.flags: %d\n", i + 1, pbones[i].flags);
  540.                 fprintf (file, "bone %d.bonecontroller: %d %d %d %d %d %d\n", i + 1, pbones[i].bonecontroller[0], pbones[i].bonecontroller[1], pbones[i].bonecontroller[2], pbones[i].bonecontroller[3], pbones[i].bonecontroller[4], pbones[i].bonecontroller[5]);
  541.                 fprintf (file, "bone %d.value: %f %f %f %f %f %f\n", i + 1, pbones[i].value[0], pbones[i].value[1], pbones[i].value[2], pbones[i].value[3], pbones[i].value[4], pbones[i].value[5]);
  542.                 fprintf (file, "bone %d.scale: %f %f %f %f %f %f\n", i + 1, pbones[i].scale[0], pbones[i].scale[1], pbones[i].scale[2], pbones[i].scale[3], pbones[i].scale[4], pbones[i].scale[5]);
  543.             }
  544.  
  545.             fprintf (file, "\nnumbonecontrollers: %d\n", hdr->numbonecontrollers);
  546.             for (i = 0; i < hdr->numbonecontrollers; i++)
  547.             {
  548.                 mstudiobonecontroller_t *pbonecontrollers = (mstudiobonecontroller_t *) (phdr + hdr->bonecontrollerindex);
  549.                 fprintf (file, "\nbonecontroller %d.bone: %d\n", i + 1, pbonecontrollers[i].bone);
  550.                 fprintf (file, "bonecontroller %d.type: %d\n", i + 1, pbonecontrollers[i].type);
  551.                 fprintf (file, "bonecontroller %d.start: %f\n", i + 1, pbonecontrollers[i].start);
  552.                 fprintf (file, "bonecontroller %d.end: %f\n", i + 1, pbonecontrollers[i].end);
  553.                 fprintf (file, "bonecontroller %d.rest: %d\n", i + 1, pbonecontrollers[i].rest);
  554.                 fprintf (file, "bonecontroller %d.index: %d\n", i + 1, pbonecontrollers[i].index);
  555.             }
  556.  
  557.             fprintf (file, "\nnumhitboxes: %d\n", hdr->numhitboxes);
  558.             for (i = 0; i < hdr->numhitboxes; i++)
  559.             {
  560.                 mstudiobbox_t *pbboxes = (mstudiobbox_t *) (phdr + hdr->hitboxindex);
  561.                 fprintf (file, "\nhitbox %d.bone: %d\n", i + 1, pbboxes[i].bone);
  562.                 fprintf (file, "hitbox %d.group: %d\n", i + 1, pbboxes[i].group);
  563.                 fprintf (file, "hitbox %d.bbmin: %f %f %f\n", i + 1, pbboxes[i].bbmin[0], pbboxes[i].bbmin[1], pbboxes[i].bbmin[2]);
  564.                 fprintf (file, "hitbox %d.bbmax: %f %f %f\n", i + 1, pbboxes[i].bbmax[0], pbboxes[i].bbmax[1], pbboxes[i].bbmax[2]);
  565.             }
  566.  
  567.             fprintf (file, "\nnumseq: %d\n", hdr->numseq);
  568.             for (i = 0; i < hdr->numseq; i++)
  569.             {
  570.                 mstudioseqdesc_t *pseqdescs = (mstudioseqdesc_t *) (phdr + hdr->seqindex);
  571.                 fprintf (file, "\nseqdesc %d.label: \"%s\"\n", i + 1, pseqdescs[i].label);
  572.                 fprintf (file, "seqdesc %d.fps: %f\n", i + 1, pseqdescs[i].fps);
  573.                 fprintf (file, "seqdesc %d.flags: %d\n", i + 1, pseqdescs[i].flags);
  574.                 fprintf (file, "<...>\n");
  575.             }
  576. /*
  577.             fprintf (file, "\nnumseqgroups: %d\n", hdr->numseqgroups);
  578.             for (i = 0; i < hdr->numseqgroups; i++)
  579.             {
  580.                 mstudioseqgroup_t *pseqgroups = (mstudioseqgroup_t *) (phdr + hdr->seqgroupindex);
  581.                 fprintf (file, "\nseqgroup %d.label: \"%s\"\n", i + 1, pseqgroups[i].label);
  582.                 fprintf (file, "\nseqgroup %d.namel: \"%s\"\n", i + 1, pseqgroups[i].name);
  583.                 fprintf (file, "\nseqgroup %d.data: %d\n", i + 1, pseqgroups[i].data);
  584.             }
  585. */
  586.             hdr = g_studioModel.getTextureHeader ();
  587.             fprintf (file, "\nnumtextures: %d\n", hdr->numtextures);
  588.             fprintf (file, "textureindex: %d\n", hdr->textureindex);
  589.             fprintf (file, "texturedataindex: %d\n", hdr->texturedataindex);
  590.             for (i = 0; i < hdr->numtextures; i++)
  591.             {
  592.                 mstudiotexture_t *ptextures = (mstudiotexture_t *) ((byte *) hdr + hdr->textureindex);
  593.                 fprintf (file, "\ntexture %d.name: \"%s\"\n", i + 1, ptextures[i].name);
  594.                 fprintf (file, "texture %d.flags: %d\n", i + 1, ptextures[i].flags);
  595.                 fprintf (file, "texture %d.width: %d\n", i + 1, ptextures[i].width);
  596.                 fprintf (file, "texture %d.height: %d\n", i + 1, ptextures[i].height);
  597.                 fprintf (file, "texture %d.index: %d\n", i + 1, ptextures[i].index);
  598.             }
  599.  
  600.             hdr = g_studioModel.getStudioHeader ();
  601.             fprintf (file, "\nnumskinref: %d\n", hdr->numskinref);
  602.             fprintf (file, "numskinfamilies: %d\n", hdr->numskinfamilies);
  603.  
  604.             fprintf (file, "\nnumbodyparts: %d\n", hdr->numbodyparts);
  605.             for (i = 0; i < hdr->numbodyparts; i++)
  606.             {
  607.                 mstudiobodyparts_t *pbodyparts = (mstudiobodyparts_t *) ((byte *) hdr + hdr->bodypartindex);
  608.                 fprintf (file, "\nbodypart %d.name: \"%s\"\n", i + 1, pbodyparts[i].name);
  609.                 fprintf (file, "bodypart %d.nummodels: %d\n", i + 1, pbodyparts[i].nummodels);
  610.                 fprintf (file, "bodypart %d.base: %d\n", i + 1, pbodyparts[i].base);
  611.                 fprintf (file, "bodypart %d.modelindex: %d\n", i + 1, pbodyparts[i].modelindex);
  612.             }
  613.  
  614.             fprintf (file, "\nnumattachments: %d\n", hdr->numattachments);
  615.             for (i = 0; i < hdr->numattachments; i++)
  616.             {
  617.                 mstudioattachment_t *pattachments = (mstudioattachment_t *) ((byte *) hdr + hdr->attachmentindex);
  618.                 fprintf (file, "attachment %d.name: \"%s\"\n", i + 1, pattachments[i].name);
  619.             }
  620.  
  621.             fclose (file);
  622.  
  623.             ShellExecute ((HWND) getHandle (), "open", "midump.txt", 0, 0, SW_SHOW);
  624.         }
  625.     }
  626. #endif
  627. }
  628.  
  629.  
  630.  
  631. void
  632. ControlPanel::loadModel (const char *filename)
  633. {
  634.     g_studioModel.FreeModel ();
  635.     if (g_studioModel.LoadModel ((char *) filename))
  636.     {
  637.         if (g_studioModel.PostLoadModel ((char *) filename))
  638.         {
  639.             initSequences ();
  640.             initBodyparts ();
  641.             initBoneControllers ();
  642.             initSkins ();
  643.             initTextures ();
  644.             centerView ();
  645.             strcpy (g_viewerSettings.modelFile, filename);
  646.             setModelInfo ();
  647.             g_viewerSettings.sequence = 0;
  648.             g_viewerSettings.speedScale = 1.0f;
  649.             slSpeedScale->setValue (40);
  650.             int i;
  651.             for (i = 0; i < 32; i++)
  652.                 g_viewerSettings.submodels[i] = 0;
  653.             for (i = 0; i < 8; i++)
  654.                 g_viewerSettings.controllers[i] = 0;
  655.  
  656.             mx_setcwd (mx_getpath (filename));
  657.         }
  658.         else
  659.             mxMessageBox (this, "Error post-loading model.", g_appTitle, MX_MB_ERROR | MX_MB_OK);
  660.     }
  661.     else
  662.         mxMessageBox (this, "Error loading model.", g_appTitle, MX_MB_ERROR | MX_MB_OK);
  663. }
  664.  
  665.  
  666.  
  667. void
  668. ControlPanel::setRenderMode (int mode)
  669. {
  670.     g_viewerSettings.renderMode = mode;
  671.     d_GlWindow->redraw ();
  672. }
  673.  
  674.  
  675.  
  676. void
  677. ControlPanel::setShowGround (bool b)
  678. {
  679.     g_viewerSettings.showGround = b;
  680.     cbGround->setChecked (b);
  681.     if (!b)
  682.     {
  683.         cbMirror->setChecked (b);
  684.         g_viewerSettings.mirror = b;
  685.     }
  686. }
  687.  
  688.  
  689.  
  690. void
  691. ControlPanel::setMirror (bool b)
  692. {
  693.     g_viewerSettings.useStencil = (!g_viewerSettings.use3dfx && b);
  694.     g_viewerSettings.mirror = b;
  695.     cbMirror->setChecked (b);
  696.     if (b)
  697.     {
  698.         cbGround->setChecked (b);
  699.         g_viewerSettings.showGround = b;
  700.     }
  701. }
  702.  
  703.  
  704.  
  705. void
  706. ControlPanel::setShowBackground (bool b)
  707. {
  708.     g_viewerSettings.showBackground = b;
  709.     cbBackground->setChecked (b);
  710. }
  711.  
  712.  
  713.  
  714. void
  715. ControlPanel::initSequences ()
  716. {
  717.     studiohdr_t *hdr = g_studioModel.getStudioHeader ();
  718.     if (hdr)
  719.     {
  720.         cSequence->removeAll ();
  721.         for (int i = 0; i < hdr->numseq; i++)
  722.         {
  723.             mstudioseqdesc_t *pseqdescs = (mstudioseqdesc_t *) ((byte *) hdr + hdr->seqindex);
  724.             cSequence->add (pseqdescs[i].label);
  725.         }
  726.  
  727.         cSequence->select (0);
  728.     }
  729. }
  730.  
  731.  
  732.  
  733. void
  734. ControlPanel::setSequence (int index)
  735. {
  736.     cSequence->select (index);
  737.     g_studioModel.SetSequence(index);
  738.     g_viewerSettings.sequence = index;
  739. }
  740.  
  741.  
  742.  
  743. void
  744. ControlPanel::initBodyparts ()
  745. {
  746.     studiohdr_t *hdr = g_studioModel.getStudioHeader ();
  747.     if (hdr)
  748.     {
  749.         int i;
  750.         mstudiobodyparts_t *pbodyparts = (mstudiobodyparts_t *) ((byte *) hdr + hdr->bodypartindex);
  751.  
  752.         cBodypart->removeAll ();
  753.         if (hdr->numbodyparts > 0)
  754.         {
  755.             for (i = 0; i < hdr->numbodyparts; i++)
  756.                 cBodypart->add (pbodyparts[i].name);
  757.  
  758.             cBodypart->select (0);
  759.  
  760.             cSubmodel->removeAll ();
  761.             for (i = 0; i < pbodyparts[0].nummodels; i++)
  762.             {
  763.                 char str[64];
  764.                 sprintf (str, "Submodel %d", i + 1);
  765.                 cSubmodel->add (str);
  766.             }
  767.             cSubmodel->select (0);
  768.         }
  769.     }
  770. }
  771.  
  772.  
  773.  
  774. void
  775. ControlPanel::setBodypart (int index)
  776. {
  777.     studiohdr_t *hdr = g_studioModel.getStudioHeader ();
  778.     if (hdr)
  779.     {
  780.         //cBodypart->setEn
  781.         cBodypart->select (index);
  782.         if (index < hdr->numbodyparts)
  783.         {
  784.             mstudiobodyparts_t *pbodyparts = (mstudiobodyparts_t *) ((byte *) hdr + hdr->bodypartindex);
  785.             cSubmodel->removeAll ();
  786.         
  787.             for (int i = 0; i < pbodyparts[index].nummodels; i++)
  788.             {
  789.                 char str[64];
  790.                 sprintf (str, "Submodel %d", i + 1);
  791.                 cSubmodel->add (str);
  792.             }
  793.             cSubmodel->select (0);
  794.             //g_studioModel.SetBodygroup (index, 0);
  795.         }
  796.     }
  797. }
  798.  
  799.  
  800.  
  801. void
  802. ControlPanel::setSubmodel (int index)
  803. {
  804.     g_studioModel.SetBodygroup (cBodypart->getSelectedIndex (), index);
  805.     g_viewerSettings.submodels[cBodypart->getSelectedIndex ()] = index;
  806. }
  807.  
  808.  
  809.  
  810. void
  811. ControlPanel::initBoneControllers ()
  812. {
  813.     studiohdr_t *hdr = g_studioModel.getStudioHeader ();
  814.     if (hdr)
  815.     {
  816.         cController->setEnabled (hdr->numbonecontrollers > 0);
  817.         slController->setEnabled (hdr->numbonecontrollers > 0);
  818.         cController->removeAll ();
  819.  
  820.         mstudiobonecontroller_t *pbonecontrollers = (mstudiobonecontroller_t *) ((byte *) hdr + hdr->bonecontrollerindex);
  821.         for (int i = 0; i < hdr->numbonecontrollers; i++)
  822.         {
  823.             char str[32];
  824.             if (pbonecontrollers[i].index == 4)
  825.                 sprintf (str, "Mouth");
  826.             else
  827.                 sprintf (str, "Controller %d", pbonecontrollers[i].index);
  828.             cController->add (str);
  829.         }
  830.  
  831.         if (hdr->numbonecontrollers > 0)
  832.         {
  833.             cController->select (0);
  834.             slController->setRange ((int) pbonecontrollers[0].start, (int) pbonecontrollers[0].end);
  835.             slController->setValue (0);
  836.         }
  837.  
  838.     }
  839. }
  840.  
  841.  
  842.  
  843. void
  844. ControlPanel::setBoneController (int index)
  845. {
  846.     studiohdr_t *hdr = g_studioModel.getStudioHeader ();
  847.     if (hdr)
  848.     {
  849.         mstudiobonecontroller_t *pbonecontrollers = (mstudiobonecontroller_t *) ((byte *) hdr + hdr->bonecontrollerindex);
  850.         slController->setRange ((int) pbonecontrollers[index].start, (int) pbonecontrollers[index].end);
  851.         slController->setValue (0);
  852.     }
  853. }
  854.  
  855.  
  856.  
  857. void
  858. ControlPanel::setBoneControllerValue (int index, float value)
  859. {
  860.     studiohdr_t *hdr = g_studioModel.getStudioHeader ();
  861.     if (hdr)
  862.     {
  863.         mstudiobonecontroller_t *pbonecontrollers = (mstudiobonecontroller_t *) ((byte *) hdr + hdr->bonecontrollerindex);
  864.         if (pbonecontrollers[index].index == 4)
  865.             g_studioModel.SetMouth (value);
  866.         else
  867.             g_studioModel.SetController (pbonecontrollers[index].index, value);
  868.     
  869.         g_viewerSettings.controllers[index] = value;
  870.     }
  871. }
  872.  
  873.  
  874.  
  875. void
  876. ControlPanel::initSkins ()
  877. {
  878.     studiohdr_t *hdr = g_studioModel.getStudioHeader ();
  879.     if (hdr)
  880.     {
  881.         cSkin->setEnabled (hdr->numskinfamilies > 0);
  882.         cSkin->removeAll ();
  883.  
  884.         for (int i = 0; i < hdr->numskinfamilies; i++)
  885.         {
  886.             char str[32];
  887.             sprintf (str, "Skin %d", i + 1);
  888.             cSkin->add (str);
  889.         }
  890.  
  891.         cSkin->select (0);
  892.         g_studioModel.SetSkin (0);
  893.         g_viewerSettings.skin = 0;
  894.     }
  895. }
  896.  
  897.  
  898.  
  899. void
  900. ControlPanel::setModelInfo ()
  901. {
  902.     static char str[2048];
  903.     studiohdr_t *hdr = g_studioModel.getStudioHeader ();
  904.  
  905.     if (!hdr)
  906.         return;
  907.  
  908.     sprintf (str,
  909.         "Bones: %d\n"
  910.         "Bone Controllers: %d\n"
  911.         "Hit Boxes: %d\n"
  912.         "Sequences: %d\n"
  913.         "Sequence Groups: %d\n",
  914.         hdr->numbones,
  915.         hdr->numbonecontrollers,
  916.         hdr->numhitboxes,
  917.         hdr->numseq,
  918.         hdr->numseqgroups
  919.         );
  920.  
  921.     lModelInfo1->setLabel (str);
  922.  
  923.     sprintf (str,
  924.         "Textures: %d\n"
  925.         "Skin Families: %d\n"
  926.         "Bodyparts: %d\n"
  927.         "Attachments: %d\n"
  928.         "Transitions: %d\n",
  929.         hdr->numtextures,
  930.         hdr->numskinfamilies,
  931.         hdr->numbodyparts,
  932.         hdr->numattachments,
  933.         hdr->numtransitions);
  934.  
  935.     lModelInfo2->setLabel (str);
  936. }
  937.  
  938.  
  939.  
  940. void
  941. ControlPanel::initTextures ()
  942. {
  943.     studiohdr_t *hdr = g_studioModel.getTextureHeader ();
  944.     if (hdr)
  945.     {
  946.         cTextures->removeAll ();
  947.         mstudiotexture_t *ptextures = (mstudiotexture_t *) ((byte *) hdr + hdr->textureindex);
  948.         for (int i = 0; i < hdr->numtextures; i++)
  949.             cTextures->add (ptextures[i].name);
  950.         cTextures->select (0);
  951.         g_viewerSettings.texture = 0;
  952.         if (hdr->numtextures > 0)
  953.             cbChrome->setChecked ((ptextures[0].flags & STUDIO_NF_CHROME) == STUDIO_NF_CHROME);
  954.     }
  955. }
  956.  
  957.  
  958.  
  959. void
  960. ControlPanel::centerView ()
  961. {
  962.     float min[3], max[3];
  963.     g_studioModel.ExtractBbox (min, max);
  964.  
  965.     float dx = max[0] - min[0];
  966.     float dy = max[1] - min[1];
  967.     float dz = max[2] - min[2];
  968.     float d = dx;
  969.     if (dy > d)
  970.         d = dy;
  971.     if (dz > d)
  972.         d = dz;
  973.     g_viewerSettings.trans[0] = 0;
  974.     g_viewerSettings.trans[1] = min[2] + dz / 2;
  975.     g_viewerSettings.trans[2] = d * 1.0f;
  976.     g_viewerSettings.rot[0] = -90.0f;
  977.     g_viewerSettings.rot[1] = -90.0f;
  978.     g_viewerSettings.rot[2] = 0.0f;
  979.     d_GlWindow->redraw ();
  980. }
  981.  
  982.  
  983.  
  984. #ifdef WIN32
  985. void
  986. ControlPanel::fullscreen ()
  987. {
  988.     //g_viewerSettings.use3dfx = cb3dfxOpenGL->isChecked ();
  989.     swap3dfxgl (g_viewerSettings.use3dfx);
  990.  
  991.     char szName[256];
  992.  
  993.     GetModuleFileName (NULL, szName, 256);
  994.     char *ptr = strrchr (szName, '\\');
  995.     *ptr = '\0';
  996.     SetCurrentDirectory (szName);
  997.  
  998.     g_viewerSettings.width = atoi (leWidth->getLabel ());
  999.     g_viewerSettings.height = atoi (leHeight->getLabel ());
  1000.     g_viewerSettings.cds = true;
  1001.     //g_viewerSettings.use3dfx = cb3dfxOpenGL->isChecked ();
  1002.  
  1003.     if (SaveViewerSettings ("hlmv.cfg"))
  1004.     {
  1005.         g_viewerSettings.pause = true;
  1006.         g_viewerSettings.use3dfx = false;
  1007.         WinExec ("hlmv.exe -fullscreen", SW_SHOW);
  1008.     }
  1009. }
  1010. #endif
  1011.